﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GDoc.Data;
using System.IO;

namespace GDoc.Domain.Services
{
    public static class FileSystem
    {
        public static string Combine(string path, string name)
        {
            string folderName = String.Format("{0}/{1}", path, name).Replace("//", "/");

            if (folderName.StartsWith("/"))
                folderName = folderName.Substring(1, folderName.Length - 1);

            if (folderName.EndsWith("/"))
                folderName = folderName.Substring(0, folderName.Length - 1);

            return folderName;
        }

        public static FileSystemEntry CreateFolder(long accountId, string name, string path)
        {
            path = path ?? string.Empty;

            string fullPath = FileSystem.Combine(path, name);

            FileSystemEntry entry = new FileSystemEntry
            {
                AccountId = accountId,
                Name = name,
                Path = path,
                FullPath = fullPath,
                Created = DateTime.Now,
                Modified = DateTime.Now,
                Size = 0,
                Type = (int)FileSystemEntryType.Folder
            };

            RepositoryFactory.CreateFileSystemEntriesRepository().Add(entry);

            return entry;
        }

        public static FileSystemEntry CreateFile(long accountId, string name, string path, string contentType, int size)
        {
            path = path ?? string.Empty;

            string fullPath = FileSystem.Combine(path, name);

            FileSystemEntry entry = new FileSystemEntry
            {
                AccountId = accountId,
                Name = name,
                Path = path,
                FullPath = fullPath,
                Created = DateTime.Now,
                Modified = DateTime.Now,
                ContentType = contentType,
                Size = size,
                Type = (int)FileSystemEntryType.File
            };

            RepositoryFactory.CreateFileSystemEntriesRepository().Add(entry);

            return entry;
        }

        public static IEnumerable<FileSystemEntry> Browse(long id, string path)
        {
            path = path ?? string.Empty;

            return RepositoryFactory.CreateFileSystemEntriesRepository().Browse(id, path);
        }

        public static FileSystemEntry GetFile(long id, string path)
        {
            path = path ?? string.Empty;

            return RepositoryFactory.CreateFileSystemEntriesRepository().Get(id, path);
        }

        public static Stream GetFileContent(long id, string path)
        {
            string urn = String.Format("urn:blob:{0}|{1}", id, path.Replace('/', '|'));

            return RepositoryFactory.CreateFilesRepository().Get(urn);
        }

        public static string UploadFileContent(long id, string path, Stream stream)
        {
            string urn = String.Format("urn:blob:{0}|{1}", id, path.Replace('/', '|'));

            return RepositoryFactory.CreateFilesRepository().Save(urn, stream);
        }

        public static bool Remove(long id, string path)
        {
            var entry = GetFile(id, path);
            string urn = String.Format("urn:blob:{0}|{1}", id, path.Replace('/', '|'));

            if (entry == null)
                return true;

            if (entry.Type == (int)FileSystemEntryType.File)
            {
                RepositoryFactory.CreateFileSystemEntriesRepository().Remove(entry);
                RepositoryFactory.CreateFilesRepository().Remove(urn);

                return true;
            }
            else
            {
                var content = Browse(id, path);

                if (content.Count() > 0)
                {
                    return false;
                }

                RepositoryFactory.CreateFileSystemEntriesRepository().Remove(entry);
                RepositoryFactory.CreateFilesRepository().Remove(urn);

                return true;
            }
        }
    }


    public enum FileSystemEntryType
    {
        Folder = 0,
        File = 1
    }
}
